package com.miracle9.game.thread;

import com.miracle9.game.util.GameParameterAssist;
import com.miracle9.game.util.MyUtil;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.springframework.stereotype.Service;
import wox.serial.EncodeBase64;
import wox.serial.SimpleWriter;
import wox.serial.XMLUtil;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service("sessionThread")
public class SessionThread
        extends Thread {

    private Logger logger = Logger.getLogger(SessionThread.class);

    @PostConstruct
    public void sessionThreadStart() {
        start();
    }

    public void run() {
        try {
            for (; ; ) {
                for (Iterator it = GameParameterAssist.bg.keySet().iterator(); it
                        .hasNext(); ) {
                    IoSession session = (IoSession) it.next();
                    Long value = (Long) GameParameterAssist.bg.get(session);
                    if ((value != null) &&
                            (System.currentTimeMillis() >= value.longValue() + 3000L)) {
                        if (!GameParameterAssist.bd.containsKey(session)) {
                            Map arg = new HashMap();
                            String key = MyUtil.substringLength(16);
                            GameParameterAssist.bd.put(session, key);

                            String indexStr = key.substring(0, 1);
                            String lastStr = key.substring(key.length() - 1,
                                    key.length());
                            key = key.substring(1, key.length() - 1);
                            StringBuilder sb = new StringBuilder(key);
                            key = indexStr + sb.reverse().toString() + lastStr;
                            byte[] keys = EncodeBase64.encode(key.getBytes());
                            key = new String(keys);

                            arg.put("key", key);
                            arg.put("time",
                                    Long.valueOf(System.currentTimeMillis()));
                            HashMap map = new HashMap();
                            map.put("method", "sendServerTime");
                            map.put("args", new Object[]{arg});
                            SimpleWriter w = new SimpleWriter();
                            String str = XMLUtil.element2String(w.write(map));
                            byte[] content = str.getBytes("UTF-8");
                            IoBuffer bb = IoBuffer.allocate(content.length + 4);
                            bb.putInt(content.length);
                            bb.put(content);
                            bb.flip();
                            session.write(bb);
                            if (System.currentTimeMillis() - value.longValue() > 32000L) {
                                session.close(true);
                                it.remove();
                            }
                        }
                    }
                }
                for (Iterator pit = GameParameterAssist.bA.keySet().iterator(); pit
                        .hasNext(); ) {
                    IoSession session = (IoSession) pit.next();

                    Long key = (Long) GameParameterAssist.bg.get(session);
                    if ((key != null) &&
                            (System.currentTimeMillis() - key.longValue() > 150000L)) {
                        session.close(true);
                        pit.remove();
                    }
                }
                kickAttackSession();

                sleep(1000L);
            }
        } catch (Exception e) {
            this.logger.error("", e);
        }
    }

    public void kickAttackSession() {
        try {
            Iterator it = GameParameterAssist.bg.keySet().iterator();
            while (it.hasNext()) {
                IoSession key = (IoSession) it.next();
                Long value = GameParameterAssist.bg.get(key);
                if (System.currentTimeMillis() - value.longValue() > 5000L) {
                    String attack = (String) key.getAttribute("attack");
                    String trueClient = (String) key.getAttribute("trueClient");
                    String needRemove = (String) key.getAttribute("needRemove");
                    if ((attack == null) || (needRemove != null)) {
                        key.close(true);
                        it.remove();
                    }
                }
            }
        } catch (Exception e) {
            this.logger.error("kickAttackSession error:", e);
        }
    }

}
